<?php
/**
 * 程序基础类
 * 
 * Created		: 2010-06-04
 * Modified		: 2011-07-20 
 * @link		: http://www.phpfo.com
 * @copyright	: (C) 2011 Qixbo Inc.
 * @version		: 0.2.1
 * @author		: Joseph Chen (jsph.chen@gmail.com)
 */
class App
{
	private static $init = 0;
	private static $args = array();
	
	private static $include_js = array();
	private static $include_css = array();
	
	private static $open_throw = 1;
	
	// 是否自动输出缓存
	private static $ob_auto_output = true;
	// 控制view是否继续执行
	private static $view = true;
	
	private static $origin_db_driver = '';
	
	/**
	 * 运行程序
	 */
	public static function run()
	{
		self::initialize();
	}
	
	public static function initialize()
	{
		
		
		return true;
	}
	
	/**
	 * 设置属性
	 * @param $var 属性名
	 * @param $val 属性值
	 */
	public static function set($var, $val)
	{
		self::${$var} = $val;
	}
	
	/**
	 * 获取属性值
	 * @param $var 属性名
	 * @param $val 属性值
	 */
	public static function get($var)
	{
		return self::${$var};
	}
	
	/**
	 * 设置参数
	 * @param array $vars
	 */
	public static function setOptions($vars=array())
	{
		self::$init = 1;
		if (empty($vars))
		{
			$vars = array(
				'app_theme'   => $GLOBALS['app_theme'],
				'suffix_tpl'  => $GLOBALS['suffix_tpl'],
				'theme'       => $GLOBALS['theme'],
				'theme_dir'   => $GLOBALS['theme_dir'],
				'app_cache_tpl' => $GLOBALS['app_cache_tpl'],
				'app_theme_css' => $GLOBALS['app_theme_css'],
				'app_theme_js' => $GLOBALS['app_theme_js'],
				'url_tpl_css' => $GLOBALS['url_tpl_css'],
				'url_tpl_js' => $GLOBALS['url_tpl_js'],
				'url_js' => $GLOBALS['url_js'],
			);
		} else {
			isset($vars['app_theme']) || $vars['app_theme'] = $GLOBALS['app_theme'];
			isset($vars['suffix_tpl']) || $vars['suffix_tpl'] = $GLOBALS['suffix_tpl'];
			isset($vars['theme']) || $vars['theme'] = $GLOBALS['theme'];
			isset($vars['theme_dir']) || $vars['theme_dir'] = $GLOBALS['theme_dir'];
			isset($vars['app_cache_tpl']) || $vars['app_cache_tpl'] = $GLOBALS['app_cache_tpl'];
			isset($vars['app_theme_css']) || $vars['app_theme_css'] = $GLOBALS['app_theme_css'];
			isset($vars['app_theme_js']) || $vars['app_theme_js'] = $GLOBALS['app_theme_js'];
			isset($vars['url_tpl_css']) || $vars['url_tpl_css'] = $GLOBALS['url_tpl_css'];
			isset($vars['url_tpl_js']) || $vars['url_tpl_js'] = $GLOBALS['url_tpl_js'];
			isset($vars['url_js']) || $vars['url_js'] = $GLOBALS['url_js'];
		}
		isset($vars['script_name']) || $vars['script_name'] = basename($_SERVER['SCRIPT_NAME'], '.php');
		self::$args = $vars;
		Tpl::init($vars);
	}
	
	/**
	 * 显示页面
	 * @return string
	 */
	public static function view()
	{
		if (!self::$view) {
			return true;
		}
		if (!self::$init) {
			self::setOptions();
		}
		$arg = func_get_args();
		if (empty($arg))
		{
			$arg = array(0, self::$args['script_name']);
		} elseif (!isset ($arg[1])) {
			$arg[1] = self::$args['script_name'];
		}
		if ($arg[0]===1 || $arg[0]===true)
		{
			$autoHf = array('header','footer');
			$tpl = $arg[1];
		} elseif (is_array($arg[0])){
			$autoHf = $arg[0];
			$tpl = $arg[1];
		} else {
			$autoHf = 0;
			$tpl = (is_string($arg[0])) ? $arg[0] : self::$args['script_name'];
			if (is_string($arg[0]))
			{
				$more_tpl = explode(',', $arg[0]);
			} elseif (is_array($arg[0])) {
				$more_tpl = $arg[0];
			} elseif (is_string($arg[1])) {
				$more_tpl = explode(',', $arg[1]);
			} elseif (is_array($arg[1])) {
				$more_tpl = $arg[1];
			}
		}
		
		extract($GLOBALS);

		if ($autoHf)
		{
			include Tpl::load($autoHf[0]);
			include Tpl::load($tpl);
			include Tpl::load($autoHf[1]);
		} else {
			foreach ($more_tpl as $tpl)
			{
				include Tpl::load($tpl);
			}
		}
		if (self::$ob_auto_output) {
			ob_end_flush();
		}
		return true;
	}

	/**
	 * 获取一个类的执行结果信息
	 * @param string $class
	 * @return array
	 */
	public static function get_g_msg($class, $success_code=0)
	{
		if (empty($success_code)) $success_code = $GLOBALS['LSuccessCode'];
		$class = ucfirst($class);
		if (method_exists($class, 'get')) {
			$code = call_user_func(array($class, 'get'), 'code');
			$desc = call_user_func(array($class, 'get'), 'msg');
		} else {
			$code = eval('return '.$class.'::$code;');
			$desc = eval('return '.$class.'::$msg;');
		}
		if ($success_code == $code)
		{
			$type = 'Success';
		} else {
			$type = 'Failure';
		}
		$g_msg = array(
			'type' => $type,
			'code' => $code,
			'desc' => $desc,
		);
		return $g_msg;
	}
	
	/**
	 * 切换使用的数据库类型
	 * @param string $driver
	 */
	public static function switch_db_driver($driver='')
	{
		if (!$driver) {
			if (self::$origin_db_driver == '') {
				self::$origin_db_driver = $GLOBALS['db_driver'];
				$GLOBALS['db_driver'] = 'Mysql';
			} else {
				$GLOBALS['db_driver'] = self::$origin_db_driver;
			}
		} else {
			self::$origin_db_driver = $GLOBALS['db_driver'];
			$GLOBALS['db_driver'] = $drvier;
		}
		return true;
	}
	
	/**
	 * 写数据到日志文件中
	 * @param string $file 相对于LOG路径的相对路径文件名
	 * @param string $data 要写入日志的数据
	 * @return boolean
	 */
	public static function log ($file, $data=null) {
		$file = $GLOBALS['log_root'].$file;
		mkdir(dirname($file), 0755, true);
		// 多次尝试文件是否可写,防止文件锁定写入失败
		for ($i=0; $i<5; $i++) {
			if (!file_exists($file)) {
				$fp = @fopen($file, 'ab+');
			}
			// 文件体积大于10M,重新建立新文件,以"时_分"扩展到原文件名中(不含扩展名)
			elseif ( filesize($file) > 10000000000 ) {
				$filepart = explode('.', $file);
				$file = $filepart[0].date(',H_i').$filepart[1];
			}
			if (is_writable($file)) {
				if (empty($fp)) {
					$fp = @fopen($file, 'ab+');
				}
				@flock($fp, LOCK_EX); // 文件是我的,谁也不许动
				@fwrite($fp, $data); // 迁城记录写入文件
				@flock($fp, LOCK_UN); // 用完了,谁爱用谁用去
				@fclose($fp);
				break;// 可正常写文件就跳出循环尝试
			}
			if ($i == 4) { // 试了这么多次还不能正常写入? 开辟绿色通道.
				$filename = basename($file);
				$file = $dirname.'/'.date('Y-m-d.H-i-s').'-_-'.$filename;
				if (@$fp=@fopen($file, 'ab+')) {
					@fwrite($fp, $data); // 记录写入文件
					@fclose($fp);
				}
			}
			usleep(300);//本次不能写,可能被锁定,延时一会儿再尝试
		}
		return true;
	}
}

